package com.peas.platform.module.icims.expenditure.disbursement.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.peas.platform.common.core.enums.BaseEnum;
import com.peas.platform.framework.mybatisplus.domain.BaseDomain;
import com.peas.platform.framework.mybatisplus.po.BasePo;
import com.peas.platform.framework.mybatisplus.service.BaseServiceImpl;
import com.peas.platform.module.icims.expenditure.disbursement.api.req.SaveExpenditureInternetbankReq;
import com.peas.platform.module.icims.expenditure.disbursement.api.req.SubmitExpenditureInternetbankReq;
import com.peas.platform.module.icims.expenditure.disbursement.api.req.TransactionExpenditureInternetbankReq;
import com.peas.platform.module.icims.expenditure.disbursement.controller.vo.ExpenditureInternetbankItemVo;
import com.peas.platform.module.icims.expenditure.disbursement.domain.ExpenditureInternetbankDomain;
import com.peas.platform.module.icims.expenditure.disbursement.dto.ExpenditureInternetbankDto;
import com.peas.platform.module.icims.expenditure.disbursement.dto.ExpenditureInternetbankItemDto;
import com.peas.platform.module.icims.expenditure.disbursement.enums.ExpenditureInternetbankState;
import com.peas.platform.module.icims.expenditure.disbursement.service.ExpenditureInternetbankItemService;
import com.peas.platform.module.icims.expenditure.disbursement.service.ExpenditureInternetbankService;
import com.peas.platform.module.icims.expenditure.expenses.service.ExpenditureReimbursementService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ExpenditureInternetbankServiceImpl extends BaseServiceImpl<ExpenditureInternetbankDto> implements ExpenditureInternetbankService {

    @Resource
    private ExpenditureInternetbankDomain expenditureInternetbankDomain;
    @Resource
    private ExpenditureInternetbankItemService expenditureInternetbankItemService;
    @Resource
    private ExpenditureReimbursementService expenditureReimbursementService;

    @Override
    public BaseDomain<ExpenditureInternetbankDto, ? extends BasePo> getDomain() {
        return expenditureInternetbankDomain;
    }

    @Transactional
    @Override
    public int removeById(Serializable id) {
        int result = super.removeById(id);
        List<ExpenditureInternetbankItemDto> list = expenditureInternetbankItemService.listByField("expenditureInternetbankId", id);
        List<Long> expenditureReimbursementIds = list.stream().map(ExpenditureInternetbankItemDto::getExpenditureReimbursementId).collect(Collectors.toList());
        expenditureInternetbankItemService.removeBatchByList(list);
        expenditureReimbursementService.refreshExpenditureReimbursement(expenditureReimbursementIds);
        return result;
    }

    @Transactional
    @Override
    public ExpenditureInternetbankDto saveExpenditureInternetbank(SaveExpenditureInternetbankReq vo) {
        ExpenditureInternetbankDto ekd = BeanUtil.copyProperties(vo, ExpenditureInternetbankDto.class);
        if (StrUtil.isBlank(ekd.getState())) {
            ekd.setState(ExpenditureInternetbankState.save.getKey());
        }
        int result;
        if (vo.getId() != null) {
            ExpenditureInternetbankDto bean = this.getById(vo.getId());
            ExpenditureInternetbankState state = BaseEnum.key2Enum(ExpenditureInternetbankState.class, bean.getState());
            Assert.isTrue(ExpenditureInternetbankState.save == state, "网银支付[" + bean.getInternetbankCode() + "]的状态为[" + state.getKey() + "-" + state.getValue() + "]，不允许修改");
            result = this.updateById(ekd);
        } else {
            result = this.save(ekd);
        }
        Assert.isTrue(result > 0, "保存失败");
        // items
        List<ExpenditureInternetbankItemDto> files = expenditureInternetbankItemService.listByField("expenditureInternetbankId", ekd.getId());
        expenditureInternetbankItemService.removeBatchByList(files);
        Assert.notEmpty(vo.getItems(), "请选择报账单");
        List<ExpenditureInternetbankItemDto> list = new ArrayList<>();
        CollUtil.forEach(vo.getItems(), (CollUtil.Consumer<ExpenditureInternetbankItemVo>) (value, index) -> {
            ExpenditureInternetbankItemDto dto = BeanUtil.copyProperties(value, ExpenditureInternetbankItemDto.class);
            dto.setExpenditureInternetbankId(ekd.getId());
            list.add(dto);
            Assert.notNull(dto.getExpenditureReimbursementId(), "报账单ID不能为空");
        });
        expenditureInternetbankItemService.saveBatch(list);
        List<Long> expenditureReimbursementIds = list.stream().map(ExpenditureInternetbankItemDto::getExpenditureReimbursementId).collect(Collectors.toList());
        expenditureReimbursementService.refreshExpenditureReimbursement(expenditureReimbursementIds);
        return ekd;
    }

    @Transactional
    @Override
    public void submitExpenditureInternetbank(SubmitExpenditureInternetbankReq vo) {
        Assert.notNull(vo.getApproveId(), "请选择审批模版");
        SaveExpenditureInternetbankReq v = BeanUtil.copyProperties(vo, SaveExpenditureInternetbankReq.class);
        v.setState(ExpenditureInternetbankState.submit.getKey());
        v.setItems(vo.getItems());
        v.setItems(vo.getItems());
        ExpenditureInternetbankDto ead = this.saveExpenditureInternetbank(v);
        // TODO 调银行接口
    }

    @Transactional
    @Override
    public void transactionExpenditureInternetbank(TransactionExpenditureInternetbankReq vo) {
        ExpenditureInternetbankDto dto = this.getById(vo.getExpenditureInternetbankId());
        Assert.notNull(dto, "找不到网银支付");
        Assert.equals(ExpenditureInternetbankState.submit.getKey(), dto.getState(), "只有[{}]状态的网银支付才能操作", ExpenditureInternetbankState.submit.getValue());
        dto.setTransaction(vo.getTransaction());
        dto.setTransactionMessage(vo.getTransactionMessage());
        dto.setState(ExpenditureInternetbankState.confirm.getKey());
        this.updateById(dto);
        List<ExpenditureInternetbankItemDto> list = expenditureInternetbankItemService.listByField("expenditureInternetbankId", dto.getId());
        List<Long> expenditureReimbursementIds = list.stream().map(ExpenditureInternetbankItemDto::getExpenditureReimbursementId).collect(Collectors.toList());
        expenditureReimbursementService.refreshExpenditureReimbursement(expenditureReimbursementIds);
    }

}
